1 Investigating haematopoietic progenitors from early foetal liver

In order to investigate the properties of a novel lympho-myeloid progenitor cell we isolated cells from early foetal liver

2 Transcriptional profile PCA and differential gene expression (DGA)

2.1 Sorting

Isolated cells were sorted using a variety of cell markers

2.2 RNA-seq

RNA was isolated and sequenced from the various cell types.

2.3 Sample summary

library(DT)
sample_table <- read.delim('charlotta_simplified_table.tsv', stringsAsFactors = FALSE)

rownames(sample_table) <- sample_table$Name
sample_table$Name <- NULL
sample_table$SampleID <- NULL
sample_table$batch <- c(rep("nov_18", 27), rep("mar_19",32))
sample_table$stage <- c("w12","w12","w10","w10","w10","CS19",
                        "CS19","CS19","CB","CB","CB","CS16",
                        "CS16","CB","CB","CB","w13","w13",
                        "CS20","CS20","CS20","w8","w8","w8",
                        "BM","BM","BM","BM","BM","BM","CS19"
                        ,"CS19","BM","BM","BM","BM","BM","BM",
                        "CB","CB","CB","CS2","CS2","CS2","CS2"
                        ,"CS2","CS2","w13","w13","w13","CS23",
                        "CS23","CS23","CS22","CS22","CS22",
                        "w13","w13","w13")

sample_table$diff_groups <- c(1,2,3,1,2,3,1,2,3,1,2,2,1,3,1,2,3,2,3,1,2,3,2,1,1,2,3,3,2,1,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1)

sample_table$pools <- c("W12_13","W12_13","W8_10","W8_10","W8_10","CS19_23","CS19_23","CS19_23","CB","CB","CB","CS16","CS16","CB","CB","CB","W12_13","W12_13","CS19_23","CS19_23","CS19_23","W8_10","W8_10","W8_10","BM","BM","BM","BM","BM","BM","CS19_23","CS19_23","BM","BM","BM","BM","BM","BM","CB","CB","CB","CS19_23","CS19_23","CS19_23","CS19_23","CS19_23","CS19_23","W12_13","W12_13","W12_13","CS19_23","CS19_23","CS19_23","CS19_23","CS19_23","CS19_23","W12_13","W12_13","W12_13")

datatable(sample_table) %>% 
  formatStyle("diff_groups", backgroundColor = styleEqual(c(1,2,3), c("#EAD3BF","#AA9486", "#B6854D"))) %>%
  formatStyle("pools", backgroundColor = styleEqual(c("W12_13","CS19_23","CB","W8_10","BM","CS16"), c("#9986A5","#79402E", "#CCBA72","#F3DF6C","#D9D0D3","#8D8680")))

2.4 PCA

2.4.1 PCA ‘All’ working with FPKMS and quantile normalization

library(ggplot2)
library(sva)
library(dplyr)
library(preprocessCore)
library(ggrepel)
library(Biobase)
library(tibble)
library(scater)
library(gghighlight)
library(annotables)
library(BiocParallel)
register(MulticoreParam(4))

#mar_22_19_fpkms <- read.delim('myriad/22_03_19_fpkms', header = TRUE, stringsAsFactors = FALSE ) 
#nov_20_18_fpkms <- read.delim('20_nov_2018/myriad/20_nov_18_fpkms', header = TRUE, stringsAsFactors = FALSE )

mar_22_19_fpkms <- readRDS("mar_22_19_fpkms.RDS")
nov_20_18_fpkms <- readRDS("nov_20_18_fpkms.RDS")

mar_22_19_fpkms<-dplyr::rename(mar_22_19_fpkms,
                               BM_P5_11       = C23_N728_S505,
                               BM_P10_11      = B04_N704_S503,
                               BM_P12_11      = B06_N706_S503,
                               CS19_P5_11     = B08_N710_S503,
                               CS19_P12_11    = B12_N715_S503,
                               BM1_P5_12      = B14_N718_S503,
                               BM1_P10_12     = B16_N720_S503,
                               BM1_P12_12     = B18_N722_S503,
                               BM2_P5_12      = B20_N724_S503,
                               BM2_P10_12     = B22_N727_S503,
                               BM2_P12_12     = F20_N724_S508,
                               CB_P5_12       = E23_N728_S507,
                               CB_P10_12      = D04_N704_S506,
                               CB_P12_12      = D06_N706_S506,
                               CS22_P5_12     = D08_N710_S506,
                               CS22_P10_12    = D10_N712_S506,
                               CS22_P12_12    = D12_N715_S506,
                               CS20_P5_12     = D14_N718_S506,
                               CS20_P10_12    = D16_N720_S506,
                               CS20_P12_12    = D18_N722_S506,
                               FL13w_P5_13    = D20_N724_S506,
                               FL13w_P10_13   = D22_N727_S506,
                               FL13w_P12_13   = F22_N727_S508,
                               CS23_P5_13     = G23_N728_S510,
                               CS23_P10_13    = F04_N704_S508,
                               CS23_P12_13    = F06_N706_S508,
                               CS22_P5_19     = F08_N710_S508,
                               CS22_P10_19    = F10_N712_S508,
                               CS22_P12_19    = F12_N715_S508,
                               w13_FL_P5_19   = F14_N718_S508,
                               w13_FL_P10_19  = F16_N720_S508,
                               w13_FL_P12_19  = F18_N722_S508)

fpkms <- left_join(nov_20_18_fpkms,mar_22_19_fpkms, by = c("ensgene" = "ensgene" ))
fpkms <- dplyr::rename(fpkms,symbol = symbol.x)
fpkms$symbol.y <- NULL
my_rows <- apply(fpkms[,3:length(colnames(fpkms))], 1, max) >=5;
fpkms <- fpkms[my_rows,]
fpkms <- fpkms[complete.cases(fpkms),]
temp_fpkms <- fpkms[,3:61][,order(match(colnames(fpkms[,3:61]),rownames(sample_table)))]
fpkms[,3:61]<-NULL
fpkms <- cbind(fpkms,temp_fpkms)
rm(temp_fpkms)
fpkms_counts_only <- fpkms[,3:length(colnames(fpkms))]
## Log transform the data
log.data = log2(fpkms_counts_only+1)

## Quantile normalization
normalized.data = normalize.quantiles(as.matrix(log.data)) # A quantile normalization.

## Copy the row and column names from data to data2:
rownames(normalized.data) = fpkms$ensgene
colnames(normalized.data) = colnames(fpkms[,3:length(colnames(fpkms))])

## Transpose the matrix back for PCA
normalized.data = t(normalized.data);

## =======================================================================
## Preliminary PCA pre-batch normaliztion
## =======================================================================
fit <- prcomp(normalized.data)

x="PC1"
y="PC2"
x.lab = paste(x, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == x)]^2/sum(fit$sdev^2)))
y.lab = paste(y, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == y)]^2/sum(fit$sdev^2)))
data <- data.frame(fit$x)
data<-rownames_to_column(data, var = "sample")
data<-left_join(data,rownames_to_column(sample_table, var = "sample_id"), by = c("sample" = "sample_id"))


ggplot(data,aes(PC1,PC2,colour = batch,shape = Phenotype)) + 
  geom_point(size = 2) + 
  geom_label_repel(aes(label = sample),
  size = 2,
  box.padding   = 0.1, 
  point.padding = 0.1,
  segment.color = 'grey50') +
  xlab(label = x.lab) +
  ylab(label = y.lab) +
  theme_minimal()

2.4.2 Why are they outliers?

Some of them have overrepresented sequences?

overrepresented

overrepresented

ggplot(data,aes(PC1,PC2,colour = batch,shape = Phenotype)) + geom_point(size = 2)  + gghighlight(sample == "CS22_P10_12" | sample == "CS22_P12_12" | sample == "w13_FL_P12_19") + theme_minimal()

2.4.3 Taking out the outliers

my_samples<-data[data$PC1 < 0,]$sample
normalized.data<-normalized.data[rownames(normalized.data) %in% my_samples,]

fit <- prcomp(normalized.data)
x="PC1"
y="PC2"
x.lab = paste(x, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == x)]^2/sum(fit$sdev^2)))
y.lab = paste(y, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == y)]^2/sum(fit$sdev^2)))
data <- data.frame(fit$x)
data<-rownames_to_column(data, var = "sample")
data<-left_join(data,rownames_to_column(sample_table,var = "sample_id"), by = c("sample" = "sample_id"))

ggplot(data,aes(PC1,PC2,colour = batch,shape = Phenotype)) + geom_point(size = 3) + 
                  geom_label_repel(aes(label = sample),
                  size = 2,
                  box.padding   = 0.1, 
                  point.padding = 0.1,
                  segment.color = 'grey50')  + theme_minimal()

2.4.4 Batch effect removal

my_eset <- t(normalized.data)
my_eset <- my_eset[!duplicated(rownames(my_eset)),]
my_peset <-sample_table[rownames(sample_table) %in% colnames(my_eset),]
my_eset  <- my_eset[,order(match(colnames(my_eset),rownames(my_peset)))]


pd <- new("AnnotatedDataFrame", data=my_peset)
my_eset <- ExpressionSet(assayData = my_eset, pd)

pheno <- pData(my_eset)
edata <- exprs(my_eset)

batch=pheno$batch

combat_edata1 = ComBat(dat=edata, batch=batch, mod=NULL, par.prior=TRUE, prior.plots=FALSE)
## Standardizing Data across genes
fit <- prcomp(t(combat_edata1))
x="PC1"
y="PC2"
x.lab = paste(x, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == x)]^2/sum(fit$sdev^2)))
y.lab = paste(y, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == y)]^2/sum(fit$sdev^2)))

data <- data.frame(fit$x)

data<-rownames_to_column(data, var = "sample")

data<-left_join(data,rownames_to_column(sample_table,var="sample_id"), by = c("sample" = "sample_id"))

ggplot(data,aes(PC1,PC2,colour = batch,shape = Phenotype)) + geom_point(size = 3) + 
                  geom_label_repel(aes(label = sample),
                                  size = 2,
                                  box.padding = 0.1, 
                                  point.padding = 0.1,
                                  segment.color = 'grey50') + theme_minimal()

2.4.4.1 Repeat with IL7R

il7_peset <- rownames_to_column(my_peset, var = "sample") %>% dplyr::filter( grepl("IL7R", Phenotype ))
il7_eset <- my_eset[,which(colnames(my_eset) %in% il7_peset$sample)]

pheno <- pData(il7_eset)
edata <- exprs(il7_eset)

batch=pheno$batch

combat_edata1 = ComBat(dat=edata, batch=batch, mod=NULL, par.prior=TRUE, prior.plots=FALSE)
## Standardizing Data across genes
fit <- prcomp(t(combat_edata1))
x="PC1"
y="PC2"
x.lab = paste(x, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == x)]^2/sum(fit$sdev^2)))
y.lab = paste(y, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == y)]^2/sum(fit$sdev^2)))

data <- data.frame(fit$x)

data<-rownames_to_column(data, var = "sample")

data<-left_join(data,rownames_to_column(sample_table,var="sample_id"), by = c("sample" = "sample_id"))


ggplot(data,aes(PC1,PC2,colour = stage,shape = batch)) + geom_point(size = 2) + 
                  geom_label_repel(aes(label = sample),
                  size = 2,
                  box.padding   = 0.1, 
                  point.padding = 0.1,
                  segment.color = 'grey50') +
       theme_minimal()

2.4.5 PCA without normalizing the FPKMs

fit <- prcomp(t(fpkms[,3:61]))
x="PC1"
y="PC2"
x.lab = paste(x, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == x)]^2/sum(fit$sdev^2)))
y.lab = paste(y, sprintf('(%0.1f%% explained var.)', 100 * fit$sdev[which(colnames(fit$x) == y)]^2/sum(fit$sdev^2)))
data <- data.frame(fit$x)
data <- left_join(rownames_to_column(data,var = "sample"),rownames_to_column(sample_table,var = "sample_id"), by = c("sample" = "sample_id"))

ggplot(data,aes(PC1,PC2,colour = batch)) +
  geom_point(size = 3) + 
  geom_label_repel(aes(label = sample),
  size = 2,
  box.padding   = 0.1, 
  point.padding = 0.1) 

2.5 PCA with counts

2.5.1 Using scater normalization

# mar_22_counts <- read.delim('myriad/big_counts')
# nov_20_counts <- read.delim('20_nov_2018/myriad/big_counts')
# 
# big_counts <- left_join(rownames_to_column(nov_20_counts, "ensgene"),rownames_to_column(mar_22_counts,"ensgene"))
# #matching names and orders
# 
# big_counts <- dplyr::rename(big_counts,
#                                BM_P5_11       = C23_N728_S505,
#                                BM_P10_11      = B04_N704_S503,
#                                BM_P12_11      = B06_N706_S503,
#                                CS19_P5_11     = B08_N710_S503,
#                                CS19_P12_11    = B12_N715_S503,
#                                BM1_P5_12      = B14_N718_S503,
#                                BM1_P10_12     = B16_N720_S503,
#                                BM1_P12_12     = B18_N722_S503,
#                                BM2_P5_12      = B20_N724_S503,
#                                BM2_P10_12     = B22_N727_S503,
#                                BM2_P12_12     = F20_N724_S508,
#                                CB_P5_12       = E23_N728_S507,
#                                CB_P10_12      = D04_N704_S506,
#                                CB_P12_12      = D06_N706_S506,
#                                CS22_P5_12     = D08_N710_S506,
#                                CS22_P10_12    = D10_N712_S506,
#                                CS22_P12_12    = D12_N715_S506,
#                                CS20_P5_12     = D14_N718_S506,
#                                CS20_P10_12    = D16_N720_S506,
#                                CS20_P12_12    = D18_N722_S506,
#                                FL13w_P5_13    = D20_N724_S506,
#                                FL13w_P10_13   = D22_N727_S506,
#                                FL13w_P12_13   = F22_N727_S508,
#                                CS23_P5_13     = G23_N728_S510,
#                                CS23_P10_13    = F04_N704_S508,
#                                CS23_P12_13    = F06_N706_S508,
#                                CS22_P5_19     = F08_N710_S508,
#                                CS22_P10_19    = F10_N712_S508,
#                                CS22_P12_19    = F12_N715_S508,
#                                w13_FL_P5_19   = F14_N718_S508,
#                                w13_FL_P10_19  = F16_N720_S508,
#                                w13_FL_P12_19  = F18_N722_S508)
# 
# 
# temp_counts <- big_counts[,2:60][,order(match(colnames(big_counts[,2:60]),rownames(sample_table)))]
# big_counts[2:60] <- NULL
# big_counts <- cbind(big_counts,temp_counts)
# 
# saveRDS(big_counts,"big_counts.rds")

big_counts <- readRDS('big_counts.rds')

count_matrix <- as.matrix(big_counts[,2:length(colnames(big_counts))])
colnames(count_matrix) <- rownames(sample_table)
rownames(count_matrix) <- big_counts$ensgene

sce <- SingleCellExperiment(list(counts = count_matrix),
                            colData = sample_table)
sce <- sce[rowSums(counts(sce)) >  0,]
sce <- calculateQCMetrics(sce)
## prepare total count and total features data

my_df <- data.frame("sample_id" <- colnames(sce), "total_counts" = sce$total_counts,
                    "total_features" = sce$total_features_by_counts, "batch" = sce$batch )
ggplot(my_df,aes(total_counts, fill = batch)) + geom_histogram(bins = 50) + 
  theme_minimal() + ggtitle("Histogram of total counts") + ylab("number of samples") + xlab("total counts")

ggplot(my_df,aes(total_features, fill = batch)) + geom_histogram(bins = 50) + 
  theme_minimal() + ggtitle("Histogram of total features") + ylab("number of samples") + xlab("total features")

2.5.2 PCA without batch effect removal

sizeFactors(sce) <- librarySizeFactors(sce)
sce <- normalize(sce)

sce <- runPCA(sce)

data <- reducedDim(sce)
percent_var_PC1<- paste("PC1", sprintf('(%0.1f%% explained var.)', attr(data, 'percentVar')[1] * 100 ))
percent_var_PC2<- paste("PC2", sprintf('(%0.1f%% explained var.)', attr(data, 'percentVar')[2] * 100 ))

data <- data.frame(data)
data<-left_join(rownames_to_column(data), rownames_to_column(sample_table))

ggplot(data,aes(PC1,PC2, colour = Phenotype, shape = batch )) + geom_point(size = 3 ) + 
  geom_label_repel(aes(label = rowname), size = 2,box.padding   = 0.1,point.padding = 0.1,
                   segment.color = 'grey50') + theme_minimal() + xlab(percent_var_PC1) + ylab(percent_var_PC2)

2.5.3 PCA with IL7R only

sce <- sce[,grep("IL7R", sce$Phenotype)]

sce <- runPCA(sce)

data <- reducedDim(sce)
percent_var_PC1<- paste("PC1", sprintf('(%0.1f%% explained var.)', attr(data, 'percentVar')[1] * 100 ))
percent_var_PC2<- paste("PC2", sprintf('(%0.1f%% explained var.)', attr(data, 'percentVar')[2] * 100 ))

data <- data.frame(data)
data<-left_join(rownames_to_column(data), rownames_to_column(sample_table))

ggplot(data,aes(PC1,PC2, colour = stage, shape = batch )) + geom_point(size = 3 ) + 
  geom_label_repel(aes(label = rowname), size = 2,box.padding   = 0.1,point.padding = 0.1,
                   segment.color = 'grey50') + theme_minimal() + xlab(percent_var_PC1) + ylab(percent_var_PC2)

2.6 DEseq2

library(DESeq2)
rownames(big_counts) <- big_counts$ensgene
big_counts$ensgene <- NULL
dds <- DESeqDataSetFromMatrix(big_counts, colData = sample_table, design = ~Phenotype)
my_vst <- vst(dds)

pcaData <- DESeq2::plotPCA(my_vst, intgroup =c("Phenotype","batch","stage"),returnData = TRUE)
percentVar <- round(100 * attr(pcaData, "percentVar"))


ggplot(pcaData,aes(PC1,PC2,colour = Phenotype, shape = batch)) + geom_point(size = 3 ) +
        xlab(paste0("PC1: ",percentVar[1],"% variance")) +
        ylab(paste0("PC2: ",percentVar[2],"% variance")) + 
          geom_label_repel(aes(label = name), size = 2,box.padding   = 0.1,point.padding = 0.1,
                   segment.color = 'grey50') +
        theme_minimal()

2.6.1 Genes driving PC1 and PC2

top_contribs = function(object) {
  # calculate the variance for each gene
  rv <- rowVars(assay(object))

  # select the 1000 top genes by variance
  select <- order(rv, decreasing=TRUE)[seq_len(min(1000, length(rv)))]

  # perform a PCA on the data in assay(x) for the selected genes
  pca <- prcomp(t(assay(object)[select,]))

  # the contribution to the total variance for each component
  percentVar <- pca$sdev^2 / sum( pca$sdev^2 )

  # Top 20 contributers to PC1 PC2
  PCA1_contrib <- sort(abs(pca$rotation[,1]), decreasing = TRUE )[1:20]
  PCA2_contrib <- sort(abs(pca$rotation[,2]), decreasing = TRUE )[1:20]
  PCA_contrib <- c(PCA1_contrib, PCA2_contrib)
  PCA_contrib <- data.frame("ensgene" = names(PCA_contrib), PCA_contrib)



  PCA_contrib <- cbind(PCA_contrib, data.frame("PC" = c(rep("PC1",20),rep("PC2","20"))))
  PCA_contrib <- left_join(PCA_contrib, grch38, by = "ensgene") %>% dplyr::select("PC","symbol", "biotype")
  return(PCA_contrib)
}

datatable(top_contribs(my_vst))

2.6.2 DESeq with IL7R only

dds <- dds[,colData(dds)$PCA_only_IL7R == "yes"]


my_vst <- vst(dds)

pcaData <- DESeq2::plotPCA(my_vst, intgroup =c("Phenotype","batch","stage", "pools"),returnData = TRUE)
percentVar <- round(100 * attr(pcaData, "percentVar"))


ggplot(pcaData,aes(PC1,PC2,colour = pools, shape = Phenotype )) + geom_point(size = 3 ) +
        xlab(paste0("PC1: ",percentVar[1],"% variance")) +
        ylab(paste0("PC2: ",percentVar[2],"% variance")) + 
                  geom_label_repel(aes(label = name), size = 2,box.padding   = 0.1,point.padding = 0.1,
                   segment.color = 'grey50') +
       theme_minimal() 

2.6.3 Genes driving PC1 and PC2 (IL7 only)

datatable(top_contribs(my_vst))

3 Differential Gene Expression

3.1 IL7R+KIT w12_13 v BM

coldata <- sample_table[sample_table$diff_groups == 1 & ( sample_table$pools == "W12_13" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "W12_13", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.2 IL7R+KIT w8_10 v BM

coldata <- sample_table[sample_table$diff_groups == 1 & ( sample_table$pools == "W8_10" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "W8_10", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.3 IL7R+KIT CS19_23 v BM

coldata <- sample_table[sample_table$diff_groups == 1 & ( sample_table$pools == "CS19_23" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "CS19_23", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.4 IL7R+KIT CB v BM

coldata <- sample_table[sample_table$diff_groups == 1 & ( sample_table$pools == "CB" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "CB", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.5 CD34+CD38-CD45RA- w12_13 v BM

coldata <- sample_table[sample_table$diff_groups == 2 & ( sample_table$pools == "W12_13" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "W12_13", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.6 CD34+CD38-CD45RA- w8_10 v BM

coldata <- sample_table[sample_table$diff_groups == 2 & ( sample_table$pools == "W8_10" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "W8_10", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.7 CD34+CD38-CD45RA- CS19_23 v BM

coldata <- sample_table[sample_table$diff_groups == 2 & ( sample_table$pools == "CS19_23" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "CS19_23", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.8 CD34+CD38-CD45RA- CB v BM

coldata <- sample_table[sample_table$diff_groups == 2 & ( sample_table$pools == "CB" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "CB", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.9 CD34+CD19+ w12_13 v BM

coldata <- sample_table[sample_table$diff_groups == 3 & ( sample_table$pools == "W12_13" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "W12_13", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.10 CD34+CD19+ w8_10 v BM

coldata <- sample_table[sample_table$diff_groups == 3 & ( sample_table$pools == "W8_10" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "W8_10", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.11 CD34+CD19+ CS19_23 v BM

coldata <- sample_table[sample_table$diff_groups == 3 & ( sample_table$pools == "CS19_23" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "CS19_23", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)

3.12 CD34+CD19+ CB v BM

coldata <- sample_table[sample_table$diff_groups == 3 & ( sample_table$pools == "CB" | sample_table$pools == "BM"), ]

counts <- big_counts[,colnames(big_counts) %in% rownames(coldata)]
dds <- DESeqDataSetFromMatrix(counts, colData = coldata, design = ~batch + pools)

deseq <- DESeq(dds)

res <- results(deseq, contrast = c("pools", "CB", "BM"))
resOrdered <- res[order(res$padj),]
resOrdered <- data.frame(resOrdered)
resOrdered <- resOrdered[!is.na(resOrdered$padj),]
resOrdered <- left_join(rownames_to_column(resOrdered, var = "ensgene"), grch38, by = "ensgene") %>% 
  dplyr::select(symbol,log2FoldChange,padj,biotype)
resOrdered <- resOrdered[1:500,]
datatable(resOrdered)
LS0tCnRpdGxlOiAiRXhwbG9yaW5nIEh1bWFuIFByaW1hcnkgU2FtcGxlcyIKYXV0aG9yOiA8YSBocmVmPSJodHRwczovL2NoZWxhLWphbWVzLmdpdGh1Yi5pby8iPiA8aDM+IENoZWxhIEphbWVzIDwvaDM+IDwvYT4gXG5ld2xpbmUgQ2FuY2VyIEluc3RpdHV0ZSwgVUNMLCBVSwpkYXRlOiAyMiBNYXJjaCAyMDE5Cm91dHB1dDoKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2RlcHRoOiAzCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGRmX3ByaW50OiBwYWdlZAogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAga2VlcF9tZDogZmFsc2UKICAgIGVuY29kaW5nOiAiVVRGLTgiCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpodG1sdG9vbHM6OnRhZ0xpc3Qocm1hcmtkb3duOjpodG1sX2RlcGVuZGVuY3lfZm9udF9hd2Vzb21lKCkpCmtuaXRyOjpvcHRzX2NodW5rJHNldChldmFsID0gVFJVRSwgY2FjaGUgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpCmBgYAoKCmBgYHtyLCAgb3V0LndpZHRoID0gIjEwMCUiLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0KbGlicmFyeShrbml0cikKYGBgCgojIEludmVzdGlnYXRpbmcgaGFlbWF0b3BvaWV0aWMgcHJvZ2VuaXRvcnMgZnJvbSBlYXJseSBmb2V0YWwgbGl2ZXIgCgpJbiBvcmRlciB0byBpbnZlc3RpZ2F0ZSB0aGUgcHJvcGVydGllcyBvZiBhIG5vdmVsIGx5bXBoby1teWVsb2lkIHByb2dlbml0b3IgY2VsbCB3ZSBpc29sYXRlZCBjZWxscyBmcm9tIGVhcmx5IGZvZXRhbCBsaXZlcgoKIyBUcmFuc2NyaXB0aW9uYWwgcHJvZmlsZSBQQ0EgYW5kIGRpZmZlcmVudGlhbCBnZW5lIGV4cHJlc3Npb24gKERHQSkKCiMjIFNvcnRpbmcKCklzb2xhdGVkIGNlbGxzIHdlcmUgc29ydGVkIHVzaW5nIGEgdmFyaWV0eSBvZiBjZWxsIG1hcmtlcnMKCiMjIFJOQS1zZXEKClJOQSB3YXMgaXNvbGF0ZWQgYW5kIHNlcXVlbmNlZCBmcm9tIHRoZSB2YXJpb3VzIGNlbGwgdHlwZXMuCgojIyBTYW1wbGUgc3VtbWFyeQoKYGBge3J9CmxpYnJhcnkoRFQpCnNhbXBsZV90YWJsZSA8LSByZWFkLmRlbGltKCdjaGFybG90dGFfc2ltcGxpZmllZF90YWJsZS50c3YnLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCgpyb3duYW1lcyhzYW1wbGVfdGFibGUpIDwtIHNhbXBsZV90YWJsZSROYW1lCnNhbXBsZV90YWJsZSROYW1lIDwtIE5VTEwKc2FtcGxlX3RhYmxlJFNhbXBsZUlEIDwtIE5VTEwKc2FtcGxlX3RhYmxlJGJhdGNoIDwtIGMocmVwKCJub3ZfMTgiLCAyNyksIHJlcCgibWFyXzE5IiwzMikpCnNhbXBsZV90YWJsZSRzdGFnZSA8LSBjKCJ3MTIiLCJ3MTIiLCJ3MTAiLCJ3MTAiLCJ3MTAiLCJDUzE5IiwKICAgICAgICAgICAgICAgICAgICAgICAgIkNTMTkiLCJDUzE5IiwiQ0IiLCJDQiIsIkNCIiwiQ1MxNiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJDUzE2IiwiQ0IiLCJDQiIsIkNCIiwidzEzIiwidzEzIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkNTMjAiLCJDUzIwIiwiQ1MyMCIsInc4IiwidzgiLCJ3OCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJCTSIsIkJNIiwiQk0iLCJCTSIsIkJNIiwiQk0iLCJDUzE5IgogICAgICAgICAgICAgICAgICAgICAgICAsIkNTMTkiLCJCTSIsIkJNIiwiQk0iLCJCTSIsIkJNIiwiQk0iLAogICAgICAgICAgICAgICAgICAgICAgICAiQ0IiLCJDQiIsIkNCIiwiQ1MyIiwiQ1MyIiwiQ1MyIiwiQ1MyIgogICAgICAgICAgICAgICAgICAgICAgICAsIkNTMiIsIkNTMiIsIncxMyIsIncxMyIsIncxMyIsIkNTMjMiLAogICAgICAgICAgICAgICAgICAgICAgICAiQ1MyMyIsIkNTMjMiLCJDUzIyIiwiQ1MyMiIsIkNTMjIiLAogICAgICAgICAgICAgICAgICAgICAgICAidzEzIiwidzEzIiwidzEzIikKCnNhbXBsZV90YWJsZSRkaWZmX2dyb3VwcyA8LSBjKDEsMiwzLDEsMiwzLDEsMiwzLDEsMiwyLDEsMywxLDIsMywyLDMsMSwyLDMsMiwxLDEsMiwzLDMsMiwxLDIsMSwzLDIsMSwzLDIsMSwzLDIsMSwzLDIsMSwzLDIsMSwzLDIsMSwzLDIsMSwzLDIsMSwzLDIsMSkKCnNhbXBsZV90YWJsZSRwb29scyA8LSBjKCJXMTJfMTMiLCJXMTJfMTMiLCJXOF8xMCIsIlc4XzEwIiwiVzhfMTAiLCJDUzE5XzIzIiwiQ1MxOV8yMyIsIkNTMTlfMjMiLCJDQiIsIkNCIiwiQ0IiLCJDUzE2IiwiQ1MxNiIsIkNCIiwiQ0IiLCJDQiIsIlcxMl8xMyIsIlcxMl8xMyIsIkNTMTlfMjMiLCJDUzE5XzIzIiwiQ1MxOV8yMyIsIlc4XzEwIiwiVzhfMTAiLCJXOF8xMCIsIkJNIiwiQk0iLCJCTSIsIkJNIiwiQk0iLCJCTSIsIkNTMTlfMjMiLCJDUzE5XzIzIiwiQk0iLCJCTSIsIkJNIiwiQk0iLCJCTSIsIkJNIiwiQ0IiLCJDQiIsIkNCIiwiQ1MxOV8yMyIsIkNTMTlfMjMiLCJDUzE5XzIzIiwiQ1MxOV8yMyIsIkNTMTlfMjMiLCJDUzE5XzIzIiwiVzEyXzEzIiwiVzEyXzEzIiwiVzEyXzEzIiwiQ1MxOV8yMyIsIkNTMTlfMjMiLCJDUzE5XzIzIiwiQ1MxOV8yMyIsIkNTMTlfMjMiLCJDUzE5XzIzIiwiVzEyXzEzIiwiVzEyXzEzIiwiVzEyXzEzIikKCmRhdGF0YWJsZShzYW1wbGVfdGFibGUpICU+JSAKICBmb3JtYXRTdHlsZSgiZGlmZl9ncm91cHMiLCBiYWNrZ3JvdW5kQ29sb3IgPSBzdHlsZUVxdWFsKGMoMSwyLDMpLCBjKCIjRUFEM0JGIiwiI0FBOTQ4NiIsICIjQjY4NTREIikpKSAlPiUKICBmb3JtYXRTdHlsZSgicG9vbHMiLCBiYWNrZ3JvdW5kQ29sb3IgPSBzdHlsZUVxdWFsKGMoIlcxMl8xMyIsIkNTMTlfMjMiLCJDQiIsIlc4XzEwIiwiQk0iLCJDUzE2IiksIGMoIiM5OTg2QTUiLCIjNzk0MDJFIiwgIiNDQ0JBNzIiLCIjRjNERjZDIiwiI0Q5RDBEMyIsIiM4RDg2ODAiKSkpCgpgYGAKCiMjIFBDQSAKCiMjIyBQQ0EgJ0FsbCcgd29ya2luZyB3aXRoIEZQS01TIGFuZCBbcXVhbnRpbGUgbm9ybWFsaXphdGlvbl0oaHR0cDovL2dlbm9taWNzY2xhc3MuZ2l0aHViLmlvL2Jvb2svcGFnZXMvbm9ybWFsaXphdGlvbi5odG1sKQoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShzdmEpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocHJlcHJvY2Vzc0NvcmUpCmxpYnJhcnkoZ2dyZXBlbCkKbGlicmFyeShCaW9iYXNlKQpsaWJyYXJ5KHRpYmJsZSkKbGlicmFyeShzY2F0ZXIpCmxpYnJhcnkoZ2doaWdobGlnaHQpCmxpYnJhcnkoYW5ub3RhYmxlcykKbGlicmFyeShCaW9jUGFyYWxsZWwpCnJlZ2lzdGVyKE11bHRpY29yZVBhcmFtKDQpKQoKI21hcl8yMl8xOV9mcGttcyA8LSByZWFkLmRlbGltKCdteXJpYWQvMjJfMDNfMTlfZnBrbXMnLCBoZWFkZXIgPSBUUlVFLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UgKSAKI25vdl8yMF8xOF9mcGttcyA8LSByZWFkLmRlbGltKCcyMF9ub3ZfMjAxOC9teXJpYWQvMjBfbm92XzE4X2Zwa21zJywgaGVhZGVyID0gVFJVRSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFICkKCm1hcl8yMl8xOV9mcGttcyA8LSByZWFkUkRTKCJtYXJfMjJfMTlfZnBrbXMuUkRTIikKbm92XzIwXzE4X2Zwa21zIDwtIHJlYWRSRFMoIm5vdl8yMF8xOF9mcGttcy5SRFMiKQoKbWFyXzIyXzE5X2Zwa21zPC1kcGx5cjo6cmVuYW1lKG1hcl8yMl8xOV9mcGttcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNX1A1XzExICAgICAgID0gQzIzX043MjhfUzUwNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNX1AxMF8xMSAgICAgID0gQjA0X043MDRfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNX1AxMl8xMSAgICAgID0gQjA2X043MDZfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMTlfUDVfMTEgICAgID0gQjA4X043MTBfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMTlfUDEyXzExICAgID0gQjEyX043MTVfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNMV9QNV8xMiAgICAgID0gQjE0X043MThfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNMV9QMTBfMTIgICAgID0gQjE2X043MjBfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNMV9QMTJfMTIgICAgID0gQjE4X043MjJfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNMl9QNV8xMiAgICAgID0gQjIwX043MjRfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNMl9QMTBfMTIgICAgID0gQjIyX043MjdfUzUwMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNMl9QMTJfMTIgICAgID0gRjIwX043MjRfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENCX1A1XzEyICAgICAgID0gRTIzX043MjhfUzUwNywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENCX1AxMF8xMiAgICAgID0gRDA0X043MDRfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENCX1AxMl8xMiAgICAgID0gRDA2X043MDZfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjJfUDVfMTIgICAgID0gRDA4X043MTBfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjJfUDEwXzEyICAgID0gRDEwX043MTJfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjJfUDEyXzEyICAgID0gRDEyX043MTVfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjBfUDVfMTIgICAgID0gRDE0X043MThfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjBfUDEwXzEyICAgID0gRDE2X043MjBfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjBfUDEyXzEyICAgID0gRDE4X043MjJfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMMTN3X1A1XzEzICAgID0gRDIwX043MjRfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMMTN3X1AxMF8xMyAgID0gRDIyX043MjdfUzUwNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMMTN3X1AxMl8xMyAgID0gRjIyX043MjdfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjNfUDVfMTMgICAgID0gRzIzX043MjhfUzUxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjNfUDEwXzEzICAgID0gRjA0X043MDRfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjNfUDEyXzEzICAgID0gRjA2X043MDZfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjJfUDVfMTkgICAgID0gRjA4X043MTBfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjJfUDEwXzE5ICAgID0gRjEwX043MTJfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjJfUDEyXzE5ICAgID0gRjEyX043MTVfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHcxM19GTF9QNV8xOSAgID0gRjE0X043MThfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHcxM19GTF9QMTBfMTkgID0gRjE2X043MjBfUzUwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHcxM19GTF9QMTJfMTkgID0gRjE4X043MjJfUzUwOCkKCmZwa21zIDwtIGxlZnRfam9pbihub3ZfMjBfMThfZnBrbXMsbWFyXzIyXzE5X2Zwa21zLCBieSA9IGMoImVuc2dlbmUiID0gImVuc2dlbmUiICkpCmZwa21zIDwtIGRwbHlyOjpyZW5hbWUoZnBrbXMsc3ltYm9sID0gc3ltYm9sLngpCmZwa21zJHN5bWJvbC55IDwtIE5VTEwKbXlfcm93cyA8LSBhcHBseShmcGttc1ssMzpsZW5ndGgoY29sbmFtZXMoZnBrbXMpKV0sIDEsIG1heCkgPj01OwpmcGttcyA8LSBmcGttc1tteV9yb3dzLF0KZnBrbXMgPC0gZnBrbXNbY29tcGxldGUuY2FzZXMoZnBrbXMpLF0KdGVtcF9mcGttcyA8LSBmcGttc1ssMzo2MV1bLG9yZGVyKG1hdGNoKGNvbG5hbWVzKGZwa21zWywzOjYxXSkscm93bmFtZXMoc2FtcGxlX3RhYmxlKSkpXQpmcGttc1ssMzo2MV08LU5VTEwKZnBrbXMgPC0gY2JpbmQoZnBrbXMsdGVtcF9mcGttcykKcm0odGVtcF9mcGttcykKZnBrbXNfY291bnRzX29ubHkgPC0gZnBrbXNbLDM6bGVuZ3RoKGNvbG5hbWVzKGZwa21zKSldCiMjIExvZyB0cmFuc2Zvcm0gdGhlIGRhdGEKbG9nLmRhdGEgPSBsb2cyKGZwa21zX2NvdW50c19vbmx5KzEpCgojIyBRdWFudGlsZSBub3JtYWxpemF0aW9uCm5vcm1hbGl6ZWQuZGF0YSA9IG5vcm1hbGl6ZS5xdWFudGlsZXMoYXMubWF0cml4KGxvZy5kYXRhKSkgIyBBIHF1YW50aWxlIG5vcm1hbGl6YXRpb24uCgojIyBDb3B5IHRoZSByb3cgYW5kIGNvbHVtbiBuYW1lcyBmcm9tIGRhdGEgdG8gZGF0YTI6CnJvd25hbWVzKG5vcm1hbGl6ZWQuZGF0YSkgPSBmcGttcyRlbnNnZW5lCmNvbG5hbWVzKG5vcm1hbGl6ZWQuZGF0YSkgPSBjb2xuYW1lcyhmcGttc1ssMzpsZW5ndGgoY29sbmFtZXMoZnBrbXMpKV0pCgojIyBUcmFuc3Bvc2UgdGhlIG1hdHJpeCBiYWNrIGZvciBQQ0EKbm9ybWFsaXplZC5kYXRhID0gdChub3JtYWxpemVkLmRhdGEpOwoKIyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyMgUHJlbGltaW5hcnkgUENBIHByZS1iYXRjaCBub3JtYWxpenRpb24KIyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KZml0IDwtIHByY29tcChub3JtYWxpemVkLmRhdGEpCgp4PSJQQzEiCnk9IlBDMiIKeC5sYWIgPSBwYXN0ZSh4LCBzcHJpbnRmKCcoJTAuMWYlJSBleHBsYWluZWQgdmFyLiknLCAxMDAgKiBmaXQkc2Rldlt3aGljaChjb2xuYW1lcyhmaXQkeCkgPT0geCldXjIvc3VtKGZpdCRzZGV2XjIpKSkKeS5sYWIgPSBwYXN0ZSh5LCBzcHJpbnRmKCcoJTAuMWYlJSBleHBsYWluZWQgdmFyLiknLCAxMDAgKiBmaXQkc2Rldlt3aGljaChjb2xuYW1lcyhmaXQkeCkgPT0geSldXjIvc3VtKGZpdCRzZGV2XjIpKSkKZGF0YSA8LSBkYXRhLmZyYW1lKGZpdCR4KQpkYXRhPC1yb3duYW1lc190b19jb2x1bW4oZGF0YSwgdmFyID0gInNhbXBsZSIpCmRhdGE8LWxlZnRfam9pbihkYXRhLHJvd25hbWVzX3RvX2NvbHVtbihzYW1wbGVfdGFibGUsIHZhciA9ICJzYW1wbGVfaWQiKSwgYnkgPSBjKCJzYW1wbGUiID0gInNhbXBsZV9pZCIpKQoKCmdncGxvdChkYXRhLGFlcyhQQzEsUEMyLGNvbG91ciA9IGJhdGNoLHNoYXBlID0gUGhlbm90eXBlKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAogIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gc2FtcGxlKSwKICBzaXplID0gMiwKICBib3gucGFkZGluZyAgID0gMC4xLCAKICBwb2ludC5wYWRkaW5nID0gMC4xLAogIHNlZ21lbnQuY29sb3IgPSAnZ3JleTUwJykgKwogIHhsYWIobGFiZWwgPSB4LmxhYikgKwogIHlsYWIobGFiZWwgPSB5LmxhYikgKwogIHRoZW1lX21pbmltYWwoKQoKYGBgCgoKIyMjIFdoeSBhcmUgdGhleSBvdXRsaWVycz8KClNvbWUgb2YgdGhlbSBoYXZlIG92ZXJyZXByZXNlbnRlZCBzZXF1ZW5jZXM/CgohW292ZXJyZXByZXNlbnRlZF0ob3ZlcnJlcHJlc2VudGVkLnBuZykKCmBgYHtyfQpnZ3Bsb3QoZGF0YSxhZXMoUEMxLFBDMixjb2xvdXIgPSBiYXRjaCxzaGFwZSA9IFBoZW5vdHlwZSkpICsgZ2VvbV9wb2ludChzaXplID0gMikgICsgZ2doaWdobGlnaHQoc2FtcGxlID09ICJDUzIyX1AxMF8xMiIgfCBzYW1wbGUgPT0gIkNTMjJfUDEyXzEyIiB8IHNhbXBsZSA9PSAidzEzX0ZMX1AxMl8xOSIpICsgdGhlbWVfbWluaW1hbCgpCmBgYAoKIyMjVGFraW5nIG91dCB0aGUgb3V0bGllcnMKCmBgYHtyfQpteV9zYW1wbGVzPC1kYXRhW2RhdGEkUEMxIDwgMCxdJHNhbXBsZQpub3JtYWxpemVkLmRhdGE8LW5vcm1hbGl6ZWQuZGF0YVtyb3duYW1lcyhub3JtYWxpemVkLmRhdGEpICVpbiUgbXlfc2FtcGxlcyxdCgpmaXQgPC0gcHJjb21wKG5vcm1hbGl6ZWQuZGF0YSkKeD0iUEMxIgp5PSJQQzIiCngubGFiID0gcGFzdGUoeCwgc3ByaW50ZignKCUwLjFmJSUgZXhwbGFpbmVkIHZhci4pJywgMTAwICogZml0JHNkZXZbd2hpY2goY29sbmFtZXMoZml0JHgpID09IHgpXV4yL3N1bShmaXQkc2Rldl4yKSkpCnkubGFiID0gcGFzdGUoeSwgc3ByaW50ZignKCUwLjFmJSUgZXhwbGFpbmVkIHZhci4pJywgMTAwICogZml0JHNkZXZbd2hpY2goY29sbmFtZXMoZml0JHgpID09IHkpXV4yL3N1bShmaXQkc2Rldl4yKSkpCmRhdGEgPC0gZGF0YS5mcmFtZShmaXQkeCkKZGF0YTwtcm93bmFtZXNfdG9fY29sdW1uKGRhdGEsIHZhciA9ICJzYW1wbGUiKQpkYXRhPC1sZWZ0X2pvaW4oZGF0YSxyb3duYW1lc190b19jb2x1bW4oc2FtcGxlX3RhYmxlLHZhciA9ICJzYW1wbGVfaWQiKSwgYnkgPSBjKCJzYW1wbGUiID0gInNhbXBsZV9pZCIpKQoKZ2dwbG90KGRhdGEsYWVzKFBDMSxQQzIsY29sb3VyID0gYmF0Y2gsc2hhcGUgPSBQaGVub3R5cGUpKSArIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgICAgICAgICAgICAgICAgIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gc2FtcGxlKSwKICAgICAgICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgICAgICAgICAgIGJveC5wYWRkaW5nICAgPSAwLjEsIAogICAgICAgICAgICAgICAgICBwb2ludC5wYWRkaW5nID0gMC4xLAogICAgICAgICAgICAgICAgICBzZWdtZW50LmNvbG9yID0gJ2dyZXk1MCcpICArIHRoZW1lX21pbmltYWwoKQpgYGAKCgojIyNCYXRjaCBlZmZlY3QgcmVtb3ZhbAoKYGBge3J9Cm15X2VzZXQgPC0gdChub3JtYWxpemVkLmRhdGEpCm15X2VzZXQgPC0gbXlfZXNldFshZHVwbGljYXRlZChyb3duYW1lcyhteV9lc2V0KSksXQpteV9wZXNldCA8LXNhbXBsZV90YWJsZVtyb3duYW1lcyhzYW1wbGVfdGFibGUpICVpbiUgY29sbmFtZXMobXlfZXNldCksXQpteV9lc2V0ICA8LSBteV9lc2V0WyxvcmRlcihtYXRjaChjb2xuYW1lcyhteV9lc2V0KSxyb3duYW1lcyhteV9wZXNldCkpKV0KCgpwZCA8LSBuZXcoIkFubm90YXRlZERhdGFGcmFtZSIsIGRhdGE9bXlfcGVzZXQpCm15X2VzZXQgPC0gRXhwcmVzc2lvblNldChhc3NheURhdGEgPSBteV9lc2V0LCBwZCkKCnBoZW5vIDwtIHBEYXRhKG15X2VzZXQpCmVkYXRhIDwtIGV4cHJzKG15X2VzZXQpCgpiYXRjaD1waGVubyRiYXRjaAoKY29tYmF0X2VkYXRhMSA9IENvbUJhdChkYXQ9ZWRhdGEsIGJhdGNoPWJhdGNoLCBtb2Q9TlVMTCwgcGFyLnByaW9yPVRSVUUsIHByaW9yLnBsb3RzPUZBTFNFKQoKZml0IDwtIHByY29tcCh0KGNvbWJhdF9lZGF0YTEpKQp4PSJQQzEiCnk9IlBDMiIKeC5sYWIgPSBwYXN0ZSh4LCBzcHJpbnRmKCcoJTAuMWYlJSBleHBsYWluZWQgdmFyLiknLCAxMDAgKiBmaXQkc2Rldlt3aGljaChjb2xuYW1lcyhmaXQkeCkgPT0geCldXjIvc3VtKGZpdCRzZGV2XjIpKSkKeS5sYWIgPSBwYXN0ZSh5LCBzcHJpbnRmKCcoJTAuMWYlJSBleHBsYWluZWQgdmFyLiknLCAxMDAgKiBmaXQkc2Rldlt3aGljaChjb2xuYW1lcyhmaXQkeCkgPT0geSldXjIvc3VtKGZpdCRzZGV2XjIpKSkKCmRhdGEgPC0gZGF0YS5mcmFtZShmaXQkeCkKCmRhdGE8LXJvd25hbWVzX3RvX2NvbHVtbihkYXRhLCB2YXIgPSAic2FtcGxlIikKCmRhdGE8LWxlZnRfam9pbihkYXRhLHJvd25hbWVzX3RvX2NvbHVtbihzYW1wbGVfdGFibGUsdmFyPSJzYW1wbGVfaWQiKSwgYnkgPSBjKCJzYW1wbGUiID0gInNhbXBsZV9pZCIpKQoKZ2dwbG90KGRhdGEsYWVzKFBDMSxQQzIsY29sb3VyID0gYmF0Y2gsc2hhcGUgPSBQaGVub3R5cGUpKSArIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgICAgICAgICAgICAgICAgIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gc2FtcGxlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94LnBhZGRpbmcgPSAwLjEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnQucGFkZGluZyA9IDAuMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnQuY29sb3IgPSAnZ3JleTUwJykgKyB0aGVtZV9taW5pbWFsKCkKYGBgCgojIyMjUmVwZWF0IHdpdGggSUw3UgoKYGBge3J9CmlsN19wZXNldCA8LSByb3duYW1lc190b19jb2x1bW4obXlfcGVzZXQsIHZhciA9ICJzYW1wbGUiKSAlPiUgZHBseXI6OmZpbHRlciggZ3JlcGwoIklMN1IiLCBQaGVub3R5cGUgKSkKaWw3X2VzZXQgPC0gbXlfZXNldFssd2hpY2goY29sbmFtZXMobXlfZXNldCkgJWluJSBpbDdfcGVzZXQkc2FtcGxlKV0KCnBoZW5vIDwtIHBEYXRhKGlsN19lc2V0KQplZGF0YSA8LSBleHBycyhpbDdfZXNldCkKCmJhdGNoPXBoZW5vJGJhdGNoCgpjb21iYXRfZWRhdGExID0gQ29tQmF0KGRhdD1lZGF0YSwgYmF0Y2g9YmF0Y2gsIG1vZD1OVUxMLCBwYXIucHJpb3I9VFJVRSwgcHJpb3IucGxvdHM9RkFMU0UpCgpmaXQgPC0gcHJjb21wKHQoY29tYmF0X2VkYXRhMSkpCng9IlBDMSIKeT0iUEMyIgp4LmxhYiA9IHBhc3RlKHgsIHNwcmludGYoJyglMC4xZiUlIGV4cGxhaW5lZCB2YXIuKScsIDEwMCAqIGZpdCRzZGV2W3doaWNoKGNvbG5hbWVzKGZpdCR4KSA9PSB4KV1eMi9zdW0oZml0JHNkZXZeMikpKQp5LmxhYiA9IHBhc3RlKHksIHNwcmludGYoJyglMC4xZiUlIGV4cGxhaW5lZCB2YXIuKScsIDEwMCAqIGZpdCRzZGV2W3doaWNoKGNvbG5hbWVzKGZpdCR4KSA9PSB5KV1eMi9zdW0oZml0JHNkZXZeMikpKQoKZGF0YSA8LSBkYXRhLmZyYW1lKGZpdCR4KQoKZGF0YTwtcm93bmFtZXNfdG9fY29sdW1uKGRhdGEsIHZhciA9ICJzYW1wbGUiKQoKZGF0YTwtbGVmdF9qb2luKGRhdGEscm93bmFtZXNfdG9fY29sdW1uKHNhbXBsZV90YWJsZSx2YXI9InNhbXBsZV9pZCIpLCBieSA9IGMoInNhbXBsZSIgPSAic2FtcGxlX2lkIikpCgoKZ2dwbG90KGRhdGEsYWVzKFBDMSxQQzIsY29sb3VyID0gc3RhZ2Usc2hhcGUgPSBiYXRjaCkpICsgZ2VvbV9wb2ludChzaXplID0gMikgKyAKICAgICAgICAgICAgICAgICAgZ2VvbV9sYWJlbF9yZXBlbChhZXMobGFiZWwgPSBzYW1wbGUpLAogICAgICAgICAgICAgICAgICBzaXplID0gMiwKICAgICAgICAgICAgICAgICAgYm94LnBhZGRpbmcgICA9IDAuMSwgCiAgICAgICAgICAgICAgICAgIHBvaW50LnBhZGRpbmcgPSAwLjEsCiAgICAgICAgICAgICAgICAgIHNlZ21lbnQuY29sb3IgPSAnZ3JleTUwJykgKwogICAgICAgdGhlbWVfbWluaW1hbCgpCmBgYAoKCiMjIyBQQ0Egd2l0aG91dCBub3JtYWxpemluZyB0aGUgRlBLTXMKCmBgYHtyfQpmaXQgPC0gcHJjb21wKHQoZnBrbXNbLDM6NjFdKSkKeD0iUEMxIgp5PSJQQzIiCngubGFiID0gcGFzdGUoeCwgc3ByaW50ZignKCUwLjFmJSUgZXhwbGFpbmVkIHZhci4pJywgMTAwICogZml0JHNkZXZbd2hpY2goY29sbmFtZXMoZml0JHgpID09IHgpXV4yL3N1bShmaXQkc2Rldl4yKSkpCnkubGFiID0gcGFzdGUoeSwgc3ByaW50ZignKCUwLjFmJSUgZXhwbGFpbmVkIHZhci4pJywgMTAwICogZml0JHNkZXZbd2hpY2goY29sbmFtZXMoZml0JHgpID09IHkpXV4yL3N1bShmaXQkc2Rldl4yKSkpCmRhdGEgPC0gZGF0YS5mcmFtZShmaXQkeCkKZGF0YSA8LSBsZWZ0X2pvaW4ocm93bmFtZXNfdG9fY29sdW1uKGRhdGEsdmFyID0gInNhbXBsZSIpLHJvd25hbWVzX3RvX2NvbHVtbihzYW1wbGVfdGFibGUsdmFyID0gInNhbXBsZV9pZCIpLCBieSA9IGMoInNhbXBsZSIgPSAic2FtcGxlX2lkIikpCgpnZ3Bsb3QoZGF0YSxhZXMoUEMxLFBDMixjb2xvdXIgPSBiYXRjaCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gc2FtcGxlKSwKICBzaXplID0gMiwKICBib3gucGFkZGluZyAgID0gMC4xLCAKICBwb2ludC5wYWRkaW5nID0gMC4xKSAKCmBgYAoKCgojI1BDQSB3aXRoIGNvdW50cwojIyNVc2luZyBbc2NhdGVyXShodHRwczovL2Jpb2NvbmR1Y3Rvci5vcmcvcGFja2FnZXMvcmVsZWFzZS9iaW9jL2h0bWwvc2NhdGVyLmh0bWwpIG5vcm1hbGl6YXRpb24gCgpgYGB7cn0KIyBtYXJfMjJfY291bnRzIDwtIHJlYWQuZGVsaW0oJ215cmlhZC9iaWdfY291bnRzJykKIyBub3ZfMjBfY291bnRzIDwtIHJlYWQuZGVsaW0oJzIwX25vdl8yMDE4L215cmlhZC9iaWdfY291bnRzJykKIyAKIyBiaWdfY291bnRzIDwtIGxlZnRfam9pbihyb3duYW1lc190b19jb2x1bW4obm92XzIwX2NvdW50cywgImVuc2dlbmUiKSxyb3duYW1lc190b19jb2x1bW4obWFyXzIyX2NvdW50cywiZW5zZ2VuZSIpKQojICNtYXRjaGluZyBuYW1lcyBhbmQgb3JkZXJzCiMgCiMgYmlnX2NvdW50cyA8LSBkcGx5cjo6cmVuYW1lKGJpZ19jb3VudHMsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNX1A1XzExICAgICAgID0gQzIzX043MjhfUzUwNSwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk1fUDEwXzExICAgICAgPSBCMDRfTjcwNF9TNTAzLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCTV9QMTJfMTEgICAgICA9IEIwNl9ONzA2X1M1MDMsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMTlfUDVfMTEgICAgID0gQjA4X043MTBfUzUwMywKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1MxOV9QMTJfMTEgICAgPSBCMTJfTjcxNV9TNTAzLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCTTFfUDVfMTIgICAgICA9IEIxNF9ONzE4X1M1MDMsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNMV9QMTBfMTIgICAgID0gQjE2X043MjBfUzUwMywKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk0xX1AxMl8xMiAgICAgPSBCMThfTjcyMl9TNTAzLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCTTJfUDVfMTIgICAgICA9IEIyMF9ONzI0X1M1MDMsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJNMl9QMTBfMTIgICAgID0gQjIyX043MjdfUzUwMywKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk0yX1AxMl8xMiAgICAgPSBGMjBfTjcyNF9TNTA4LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQl9QNV8xMiAgICAgICA9IEUyM19ONzI4X1M1MDcsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENCX1AxMF8xMiAgICAgID0gRDA0X043MDRfUzUwNiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0JfUDEyXzEyICAgICAgPSBEMDZfTjcwNl9TNTA2LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDUzIyX1A1XzEyICAgICA9IEQwOF9ONzEwX1M1MDYsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjJfUDEwXzEyICAgID0gRDEwX043MTJfUzUwNiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1MyMl9QMTJfMTIgICAgPSBEMTJfTjcxNV9TNTA2LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDUzIwX1A1XzEyICAgICA9IEQxNF9ONzE4X1M1MDYsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjBfUDEwXzEyICAgID0gRDE2X043MjBfUzUwNiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1MyMF9QMTJfMTIgICAgPSBEMThfTjcyMl9TNTA2LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTDEzd19QNV8xMyAgICA9IEQyMF9ONzI0X1M1MDYsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMMTN3X1AxMF8xMyAgID0gRDIyX043MjdfUzUwNiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwxM3dfUDEyXzEzICAgPSBGMjJfTjcyN19TNTA4LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDUzIzX1A1XzEzICAgICA9IEcyM19ONzI4X1M1MTAsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjNfUDEwXzEzICAgID0gRjA0X043MDRfUzUwOCwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1MyM19QMTJfMTMgICAgPSBGMDZfTjcwNl9TNTA4LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDUzIyX1A1XzE5ICAgICA9IEYwOF9ONzEwX1M1MDgsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTMjJfUDEwXzE5ICAgID0gRjEwX043MTJfUzUwOCwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1MyMl9QMTJfMTkgICAgPSBGMTJfTjcxNV9TNTA4LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3MTNfRkxfUDVfMTkgICA9IEYxNF9ONzE4X1M1MDgsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHcxM19GTF9QMTBfMTkgID0gRjE2X043MjBfUzUwOCwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzEzX0ZMX1AxMl8xOSAgPSBGMThfTjcyMl9TNTA4KQojIAojIAojIHRlbXBfY291bnRzIDwtIGJpZ19jb3VudHNbLDI6NjBdWyxvcmRlcihtYXRjaChjb2xuYW1lcyhiaWdfY291bnRzWywyOjYwXSkscm93bmFtZXMoc2FtcGxlX3RhYmxlKSkpXQojIGJpZ19jb3VudHNbMjo2MF0gPC0gTlVMTAojIGJpZ19jb3VudHMgPC0gY2JpbmQoYmlnX2NvdW50cyx0ZW1wX2NvdW50cykKIyAKIyBzYXZlUkRTKGJpZ19jb3VudHMsImJpZ19jb3VudHMucmRzIikKCmJpZ19jb3VudHMgPC0gcmVhZFJEUygnYmlnX2NvdW50cy5yZHMnKQoKY291bnRfbWF0cml4IDwtIGFzLm1hdHJpeChiaWdfY291bnRzWywyOmxlbmd0aChjb2xuYW1lcyhiaWdfY291bnRzKSldKQpjb2xuYW1lcyhjb3VudF9tYXRyaXgpIDwtIHJvd25hbWVzKHNhbXBsZV90YWJsZSkKcm93bmFtZXMoY291bnRfbWF0cml4KSA8LSBiaWdfY291bnRzJGVuc2dlbmUKCnNjZSA8LSBTaW5nbGVDZWxsRXhwZXJpbWVudChsaXN0KGNvdW50cyA9IGNvdW50X21hdHJpeCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhID0gc2FtcGxlX3RhYmxlKQpzY2UgPC0gc2NlW3Jvd1N1bXMoY291bnRzKHNjZSkpID4gIDAsXQpzY2UgPC0gY2FsY3VsYXRlUUNNZXRyaWNzKHNjZSkKCmBgYAoKYGBge3J9CiMjIHByZXBhcmUgdG90YWwgY291bnQgYW5kIHRvdGFsIGZlYXR1cmVzIGRhdGEKCm15X2RmIDwtIGRhdGEuZnJhbWUoInNhbXBsZV9pZCIgPC0gY29sbmFtZXMoc2NlKSwgInRvdGFsX2NvdW50cyIgPSBzY2UkdG90YWxfY291bnRzLAogICAgICAgICAgICAgICAgICAgICJ0b3RhbF9mZWF0dXJlcyIgPSBzY2UkdG90YWxfZmVhdHVyZXNfYnlfY291bnRzLCAiYmF0Y2giID0gc2NlJGJhdGNoICkKZ2dwbG90KG15X2RmLGFlcyh0b3RhbF9jb3VudHMsIGZpbGwgPSBiYXRjaCkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDUwKSArIAogIHRoZW1lX21pbmltYWwoKSArIGdndGl0bGUoIkhpc3RvZ3JhbSBvZiB0b3RhbCBjb3VudHMiKSArIHlsYWIoIm51bWJlciBvZiBzYW1wbGVzIikgKyB4bGFiKCJ0b3RhbCBjb3VudHMiKQpgYGAKCmBgYHtyfQoKZ2dwbG90KG15X2RmLGFlcyh0b3RhbF9mZWF0dXJlcywgZmlsbCA9IGJhdGNoKSkgKyBnZW9tX2hpc3RvZ3JhbShiaW5zID0gNTApICsgCiAgdGhlbWVfbWluaW1hbCgpICsgZ2d0aXRsZSgiSGlzdG9ncmFtIG9mIHRvdGFsIGZlYXR1cmVzIikgKyB5bGFiKCJudW1iZXIgb2Ygc2FtcGxlcyIpICsgeGxhYigidG90YWwgZmVhdHVyZXMiKQoKYGBgCgoKIyMjUENBIHdpdGhvdXQgYmF0Y2ggZWZmZWN0IHJlbW92YWwKCmBgYHtyfQpzaXplRmFjdG9ycyhzY2UpIDwtIGxpYnJhcnlTaXplRmFjdG9ycyhzY2UpCnNjZSA8LSBub3JtYWxpemUoc2NlKQoKc2NlIDwtIHJ1blBDQShzY2UpCgpkYXRhIDwtIHJlZHVjZWREaW0oc2NlKQpwZXJjZW50X3Zhcl9QQzE8LSBwYXN0ZSgiUEMxIiwgc3ByaW50ZignKCUwLjFmJSUgZXhwbGFpbmVkIHZhci4pJywgYXR0cihkYXRhLCAncGVyY2VudFZhcicpWzFdICogMTAwICkpCnBlcmNlbnRfdmFyX1BDMjwtIHBhc3RlKCJQQzIiLCBzcHJpbnRmKCcoJTAuMWYlJSBleHBsYWluZWQgdmFyLiknLCBhdHRyKGRhdGEsICdwZXJjZW50VmFyJylbMl0gKiAxMDAgKSkKCmRhdGEgPC0gZGF0YS5mcmFtZShkYXRhKQpkYXRhPC1sZWZ0X2pvaW4ocm93bmFtZXNfdG9fY29sdW1uKGRhdGEpLCByb3duYW1lc190b19jb2x1bW4oc2FtcGxlX3RhYmxlKSkKCmdncGxvdChkYXRhLGFlcyhQQzEsUEMyLCBjb2xvdXIgPSBQaGVub3R5cGUsIHNoYXBlID0gYmF0Y2ggKSkgKyBnZW9tX3BvaW50KHNpemUgPSAzICkgKyAKICBnZW9tX2xhYmVsX3JlcGVsKGFlcyhsYWJlbCA9IHJvd25hbWUpLCBzaXplID0gMixib3gucGFkZGluZyAgID0gMC4xLHBvaW50LnBhZGRpbmcgPSAwLjEsCiAgICAgICAgICAgICAgICAgICBzZWdtZW50LmNvbG9yID0gJ2dyZXk1MCcpICsgdGhlbWVfbWluaW1hbCgpICsgeGxhYihwZXJjZW50X3Zhcl9QQzEpICsgeWxhYihwZXJjZW50X3Zhcl9QQzIpCgpgYGAKCgojIyNQQ0Egd2l0aCBJTDdSIG9ubHkKCmBgYHtyfQoKc2NlIDwtIHNjZVssZ3JlcCgiSUw3UiIsIHNjZSRQaGVub3R5cGUpXQoKc2NlIDwtIHJ1blBDQShzY2UpCgpkYXRhIDwtIHJlZHVjZWREaW0oc2NlKQpwZXJjZW50X3Zhcl9QQzE8LSBwYXN0ZSgiUEMxIiwgc3ByaW50ZignKCUwLjFmJSUgZXhwbGFpbmVkIHZhci4pJywgYXR0cihkYXRhLCAncGVyY2VudFZhcicpWzFdICogMTAwICkpCnBlcmNlbnRfdmFyX1BDMjwtIHBhc3RlKCJQQzIiLCBzcHJpbnRmKCcoJTAuMWYlJSBleHBsYWluZWQgdmFyLiknLCBhdHRyKGRhdGEsICdwZXJjZW50VmFyJylbMl0gKiAxMDAgKSkKCmRhdGEgPC0gZGF0YS5mcmFtZShkYXRhKQpkYXRhPC1sZWZ0X2pvaW4ocm93bmFtZXNfdG9fY29sdW1uKGRhdGEpLCByb3duYW1lc190b19jb2x1bW4oc2FtcGxlX3RhYmxlKSkKCmdncGxvdChkYXRhLGFlcyhQQzEsUEMyLCBjb2xvdXIgPSBzdGFnZSwgc2hhcGUgPSBiYXRjaCApKSArIGdlb21fcG9pbnQoc2l6ZSA9IDMgKSArIAogIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gcm93bmFtZSksIHNpemUgPSAyLGJveC5wYWRkaW5nICAgPSAwLjEscG9pbnQucGFkZGluZyA9IDAuMSwKICAgICAgICAgICAgICAgICAgIHNlZ21lbnQuY29sb3IgPSAnZ3JleTUwJykgKyB0aGVtZV9taW5pbWFsKCkgKyB4bGFiKHBlcmNlbnRfdmFyX1BDMSkgKyB5bGFiKHBlcmNlbnRfdmFyX1BDMikKCgpgYGAKCgoKIyMgREVzZXEyCgoKYGBge3J9CmxpYnJhcnkoREVTZXEyKQpyb3duYW1lcyhiaWdfY291bnRzKSA8LSBiaWdfY291bnRzJGVuc2dlbmUKYmlnX2NvdW50cyRlbnNnZW5lIDwtIE5VTEwKZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoYmlnX2NvdW50cywgY29sRGF0YSA9IHNhbXBsZV90YWJsZSwgZGVzaWduID0gflBoZW5vdHlwZSkKbXlfdnN0IDwtIHZzdChkZHMpCgpwY2FEYXRhIDwtIERFU2VxMjo6cGxvdFBDQShteV92c3QsIGludGdyb3VwID1jKCJQaGVub3R5cGUiLCJiYXRjaCIsInN0YWdlIikscmV0dXJuRGF0YSA9IFRSVUUpCnBlcmNlbnRWYXIgPC0gcm91bmQoMTAwICogYXR0cihwY2FEYXRhLCAicGVyY2VudFZhciIpKQoKCmdncGxvdChwY2FEYXRhLGFlcyhQQzEsUEMyLGNvbG91ciA9IFBoZW5vdHlwZSwgc2hhcGUgPSBiYXRjaCkpICsgZ2VvbV9wb2ludChzaXplID0gMyApICsKICAgICAgICB4bGFiKHBhc3RlMCgiUEMxOiAiLHBlcmNlbnRWYXJbMV0sIiUgdmFyaWFuY2UiKSkgKwogICAgICAgIHlsYWIocGFzdGUwKCJQQzI6ICIscGVyY2VudFZhclsyXSwiJSB2YXJpYW5jZSIpKSArIAogICAgICAgICAgZ2VvbV9sYWJlbF9yZXBlbChhZXMobGFiZWwgPSBuYW1lKSwgc2l6ZSA9IDIsYm94LnBhZGRpbmcgICA9IDAuMSxwb2ludC5wYWRkaW5nID0gMC4xLAogICAgICAgICAgICAgICAgICAgc2VnbWVudC5jb2xvciA9ICdncmV5NTAnKSArCiAgICAgICAgdGhlbWVfbWluaW1hbCgpCgpgYGAKCiMjI0dlbmVzIGRyaXZpbmcgUEMxIGFuZCBQQzIKCmBgYHtyfQoKdG9wX2NvbnRyaWJzID0gZnVuY3Rpb24ob2JqZWN0KSB7CiAgIyBjYWxjdWxhdGUgdGhlIHZhcmlhbmNlIGZvciBlYWNoIGdlbmUKICBydiA8LSByb3dWYXJzKGFzc2F5KG9iamVjdCkpCgogICMgc2VsZWN0IHRoZSAxMDAwIHRvcCBnZW5lcyBieSB2YXJpYW5jZQogIHNlbGVjdCA8LSBvcmRlcihydiwgZGVjcmVhc2luZz1UUlVFKVtzZXFfbGVuKG1pbigxMDAwLCBsZW5ndGgocnYpKSldCgogICMgcGVyZm9ybSBhIFBDQSBvbiB0aGUgZGF0YSBpbiBhc3NheSh4KSBmb3IgdGhlIHNlbGVjdGVkIGdlbmVzCiAgcGNhIDwtIHByY29tcCh0KGFzc2F5KG9iamVjdClbc2VsZWN0LF0pKQoKICAjIHRoZSBjb250cmlidXRpb24gdG8gdGhlIHRvdGFsIHZhcmlhbmNlIGZvciBlYWNoIGNvbXBvbmVudAogIHBlcmNlbnRWYXIgPC0gcGNhJHNkZXZeMiAvIHN1bSggcGNhJHNkZXZeMiApCgogICMgVG9wIDIwIGNvbnRyaWJ1dGVycyB0byBQQzEgUEMyCiAgUENBMV9jb250cmliIDwtIHNvcnQoYWJzKHBjYSRyb3RhdGlvblssMV0pLCBkZWNyZWFzaW5nID0gVFJVRSApWzE6MjBdCiAgUENBMl9jb250cmliIDwtIHNvcnQoYWJzKHBjYSRyb3RhdGlvblssMl0pLCBkZWNyZWFzaW5nID0gVFJVRSApWzE6MjBdCiAgUENBX2NvbnRyaWIgPC0gYyhQQ0ExX2NvbnRyaWIsIFBDQTJfY29udHJpYikKICBQQ0FfY29udHJpYiA8LSBkYXRhLmZyYW1lKCJlbnNnZW5lIiA9IG5hbWVzKFBDQV9jb250cmliKSwgUENBX2NvbnRyaWIpCgoKCiAgUENBX2NvbnRyaWIgPC0gY2JpbmQoUENBX2NvbnRyaWIsIGRhdGEuZnJhbWUoIlBDIiA9IGMocmVwKCJQQzEiLDIwKSxyZXAoIlBDMiIsIjIwIikpKSkKICBQQ0FfY29udHJpYiA8LSBsZWZ0X2pvaW4oUENBX2NvbnRyaWIsIGdyY2gzOCwgYnkgPSAiZW5zZ2VuZSIpICU+JSBkcGx5cjo6c2VsZWN0KCJQQyIsInN5bWJvbCIsICJiaW90eXBlIikKICByZXR1cm4oUENBX2NvbnRyaWIpCn0KCmRhdGF0YWJsZSh0b3BfY29udHJpYnMobXlfdnN0KSkKCmBgYAoKCiMjI0RFU2VxIHdpdGggSUw3UiBvbmx5CgpgYGB7cn0KCmRkcyA8LSBkZHNbLGNvbERhdGEoZGRzKSRQQ0Ffb25seV9JTDdSID09ICJ5ZXMiXQoKCm15X3ZzdCA8LSB2c3QoZGRzKQoKcGNhRGF0YSA8LSBERVNlcTI6OnBsb3RQQ0EobXlfdnN0LCBpbnRncm91cCA9YygiUGhlbm90eXBlIiwiYmF0Y2giLCJzdGFnZSIsICJwb29scyIpLHJldHVybkRhdGEgPSBUUlVFKQpwZXJjZW50VmFyIDwtIHJvdW5kKDEwMCAqIGF0dHIocGNhRGF0YSwgInBlcmNlbnRWYXIiKSkKCgpnZ3Bsb3QocGNhRGF0YSxhZXMoUEMxLFBDMixjb2xvdXIgPSBwb29scywgc2hhcGUgPSBQaGVub3R5cGUgKSkgKyBnZW9tX3BvaW50KHNpemUgPSAzICkgKwogICAgICAgIHhsYWIocGFzdGUwKCJQQzE6ICIscGVyY2VudFZhclsxXSwiJSB2YXJpYW5jZSIpKSArCiAgICAgICAgeWxhYihwYXN0ZTAoIlBDMjogIixwZXJjZW50VmFyWzJdLCIlIHZhcmlhbmNlIikpICsgCiAgICAgICAgICAgICAgICAgIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gbmFtZSksIHNpemUgPSAyLGJveC5wYWRkaW5nICAgPSAwLjEscG9pbnQucGFkZGluZyA9IDAuMSwKICAgICAgICAgICAgICAgICAgIHNlZ21lbnQuY29sb3IgPSAnZ3JleTUwJykgKwogICAgICAgdGhlbWVfbWluaW1hbCgpIAoKYGBgCgoKIyMjR2VuZXMgZHJpdmluZyBQQzEgYW5kIFBDMiAoSUw3IG9ubHkpCgpgYGB7cn0KCmRhdGF0YWJsZSh0b3BfY29udHJpYnMobXlfdnN0KSkKCmBgYAoKCiNEaWZmZXJlbnRpYWwgR2VuZSBFeHByZXNzaW9uCgojI0lMN1IrS0lUIHcxMl8xMyB2IEJNCgoKYGBge3J9CmNvbGRhdGEgPC0gc2FtcGxlX3RhYmxlW3NhbXBsZV90YWJsZSRkaWZmX2dyb3VwcyA9PSAxICYgKCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIlcxMl8xMyIgfCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIkJNIiksIF0KCmNvdW50cyA8LSBiaWdfY291bnRzWyxjb2xuYW1lcyhiaWdfY291bnRzKSAlaW4lIHJvd25hbWVzKGNvbGRhdGEpXQpkZHMgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudHMsIGNvbERhdGEgPSBjb2xkYXRhLCBkZXNpZ24gPSB+YmF0Y2ggKyBwb29scykKCmRlc2VxIDwtIERFU2VxKGRkcykKCnJlcyA8LSByZXN1bHRzKGRlc2VxLCBjb250cmFzdCA9IGMoInBvb2xzIiwgIlcxMl8xMyIsICJCTSIpKQpyZXNPcmRlcmVkIDwtIHJlc1tvcmRlcihyZXMkcGFkaiksXQpyZXNPcmRlcmVkIDwtIGRhdGEuZnJhbWUocmVzT3JkZXJlZCkKcmVzT3JkZXJlZCA8LSBsZWZ0X2pvaW4ocm93bmFtZXNfdG9fY29sdW1uKHJlc09yZGVyZWQsIHZhciA9ICJlbnNnZW5lIiksIGdyY2gzOCwgYnkgPSAiZW5zZ2VuZSIpICU+JSAKICBkcGx5cjo6c2VsZWN0KHN5bWJvbCxsb2cyRm9sZENoYW5nZSxwYWRqLGJpb3R5cGUpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFsxOjUwMCxdCmRhdGF0YWJsZShyZXNPcmRlcmVkKQpgYGAKCiMjSUw3UitLSVQgdzhfMTAgdiBCTQoKCmBgYHtyfQpjb2xkYXRhIDwtIHNhbXBsZV90YWJsZVtzYW1wbGVfdGFibGUkZGlmZl9ncm91cHMgPT0gMSAmICggc2FtcGxlX3RhYmxlJHBvb2xzID09ICJXOF8xMCIgfCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIkJNIiksIF0KCmNvdW50cyA8LSBiaWdfY291bnRzWyxjb2xuYW1lcyhiaWdfY291bnRzKSAlaW4lIHJvd25hbWVzKGNvbGRhdGEpXQpkZHMgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudHMsIGNvbERhdGEgPSBjb2xkYXRhLCBkZXNpZ24gPSB+YmF0Y2ggKyBwb29scykKCmRlc2VxIDwtIERFU2VxKGRkcykKCnJlcyA8LSByZXN1bHRzKGRlc2VxLCBjb250cmFzdCA9IGMoInBvb2xzIiwgIlc4XzEwIiwgIkJNIikpCnJlc09yZGVyZWQgPC0gcmVzW29yZGVyKHJlcyRwYWRqKSxdCnJlc09yZGVyZWQgPC0gZGF0YS5mcmFtZShyZXNPcmRlcmVkKQpyZXNPcmRlcmVkIDwtIHJlc09yZGVyZWRbIWlzLm5hKHJlc09yZGVyZWQkcGFkaiksXQpyZXNPcmRlcmVkIDwtIGxlZnRfam9pbihyb3duYW1lc190b19jb2x1bW4ocmVzT3JkZXJlZCwgdmFyID0gImVuc2dlbmUiKSwgZ3JjaDM4LCBieSA9ICJlbnNnZW5lIikgJT4lIAogIGRwbHlyOjpzZWxlY3Qoc3ltYm9sLGxvZzJGb2xkQ2hhbmdlLHBhZGosYmlvdHlwZSkKcmVzT3JkZXJlZCA8LSByZXNPcmRlcmVkWzE6NTAwLF0KZGF0YXRhYmxlKHJlc09yZGVyZWQpCmBgYAoKIyNJTDdSK0tJVCBDUzE5XzIzIHYgQk0KCmBgYHtyfQpjb2xkYXRhIDwtIHNhbXBsZV90YWJsZVtzYW1wbGVfdGFibGUkZGlmZl9ncm91cHMgPT0gMSAmICggc2FtcGxlX3RhYmxlJHBvb2xzID09ICJDUzE5XzIzIiB8IHNhbXBsZV90YWJsZSRwb29scyA9PSAiQk0iKSwgXQoKY291bnRzIDwtIGJpZ19jb3VudHNbLGNvbG5hbWVzKGJpZ19jb3VudHMpICVpbiUgcm93bmFtZXMoY29sZGF0YSldCmRkcyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50cywgY29sRGF0YSA9IGNvbGRhdGEsIGRlc2lnbiA9IH5iYXRjaCArIHBvb2xzKQoKZGVzZXEgPC0gREVTZXEoZGRzKQoKcmVzIDwtIHJlc3VsdHMoZGVzZXEsIGNvbnRyYXN0ID0gYygicG9vbHMiLCAiQ1MxOV8yMyIsICJCTSIpKQpyZXNPcmRlcmVkIDwtIHJlc1tvcmRlcihyZXMkcGFkaiksXQpyZXNPcmRlcmVkIDwtIGRhdGEuZnJhbWUocmVzT3JkZXJlZCkKcmVzT3JkZXJlZCA8LSByZXNPcmRlcmVkWyFpcy5uYShyZXNPcmRlcmVkJHBhZGopLF0KcmVzT3JkZXJlZCA8LSBsZWZ0X2pvaW4ocm93bmFtZXNfdG9fY29sdW1uKHJlc09yZGVyZWQsIHZhciA9ICJlbnNnZW5lIiksIGdyY2gzOCwgYnkgPSAiZW5zZ2VuZSIpICU+JSAKICBkcGx5cjo6c2VsZWN0KHN5bWJvbCxsb2cyRm9sZENoYW5nZSxwYWRqLGJpb3R5cGUpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFsxOjUwMCxdCmRhdGF0YWJsZShyZXNPcmRlcmVkKQpgYGAKCiMjSUw3UitLSVQgQ0IgdiBCTQoKYGBge3J9CmNvbGRhdGEgPC0gc2FtcGxlX3RhYmxlW3NhbXBsZV90YWJsZSRkaWZmX2dyb3VwcyA9PSAxICYgKCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIkNCIiB8IHNhbXBsZV90YWJsZSRwb29scyA9PSAiQk0iKSwgXQoKY291bnRzIDwtIGJpZ19jb3VudHNbLGNvbG5hbWVzKGJpZ19jb3VudHMpICVpbiUgcm93bmFtZXMoY29sZGF0YSldCmRkcyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50cywgY29sRGF0YSA9IGNvbGRhdGEsIGRlc2lnbiA9IH5iYXRjaCArIHBvb2xzKQoKZGVzZXEgPC0gREVTZXEoZGRzKQoKcmVzIDwtIHJlc3VsdHMoZGVzZXEsIGNvbnRyYXN0ID0gYygicG9vbHMiLCAiQ0IiLCAiQk0iKSkKcmVzT3JkZXJlZCA8LSByZXNbb3JkZXIocmVzJHBhZGopLF0KcmVzT3JkZXJlZCA8LSBkYXRhLmZyYW1lKHJlc09yZGVyZWQpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFshaXMubmEocmVzT3JkZXJlZCRwYWRqKSxdCnJlc09yZGVyZWQgPC0gbGVmdF9qb2luKHJvd25hbWVzX3RvX2NvbHVtbihyZXNPcmRlcmVkLCB2YXIgPSAiZW5zZ2VuZSIpLCBncmNoMzgsIGJ5ID0gImVuc2dlbmUiKSAlPiUgCiAgZHBseXI6OnNlbGVjdChzeW1ib2wsbG9nMkZvbGRDaGFuZ2UscGFkaixiaW90eXBlKQpyZXNPcmRlcmVkIDwtIHJlc09yZGVyZWRbMTo1MDAsXQpkYXRhdGFibGUocmVzT3JkZXJlZCkKYGBgCgojI0NEMzQrQ0QzOC1DRDQ1UkEtIHcxMl8xMyB2IEJNCgpgYGB7cn0KY29sZGF0YSA8LSBzYW1wbGVfdGFibGVbc2FtcGxlX3RhYmxlJGRpZmZfZ3JvdXBzID09IDIgJiAoIHNhbXBsZV90YWJsZSRwb29scyA9PSAiVzEyXzEzIiB8IHNhbXBsZV90YWJsZSRwb29scyA9PSAiQk0iKSwgXQoKY291bnRzIDwtIGJpZ19jb3VudHNbLGNvbG5hbWVzKGJpZ19jb3VudHMpICVpbiUgcm93bmFtZXMoY29sZGF0YSldCmRkcyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50cywgY29sRGF0YSA9IGNvbGRhdGEsIGRlc2lnbiA9IH5iYXRjaCArIHBvb2xzKQoKZGVzZXEgPC0gREVTZXEoZGRzKQoKcmVzIDwtIHJlc3VsdHMoZGVzZXEsIGNvbnRyYXN0ID0gYygicG9vbHMiLCAiVzEyXzEzIiwgIkJNIikpCnJlc09yZGVyZWQgPC0gcmVzW29yZGVyKHJlcyRwYWRqKSxdCnJlc09yZGVyZWQgPC0gZGF0YS5mcmFtZShyZXNPcmRlcmVkKQpyZXNPcmRlcmVkIDwtIGxlZnRfam9pbihyb3duYW1lc190b19jb2x1bW4ocmVzT3JkZXJlZCwgdmFyID0gImVuc2dlbmUiKSwgZ3JjaDM4LCBieSA9ICJlbnNnZW5lIikgJT4lIAogIGRwbHlyOjpzZWxlY3Qoc3ltYm9sLGxvZzJGb2xkQ2hhbmdlLHBhZGosYmlvdHlwZSkKcmVzT3JkZXJlZCA8LSByZXNPcmRlcmVkWzE6NTAwLF0KZGF0YXRhYmxlKHJlc09yZGVyZWQpCmBgYAoKIyNDRDM0K0NEMzgtQ0Q0NVJBLSB3OF8xMCB2IEJNCgoKYGBge3J9CmNvbGRhdGEgPC0gc2FtcGxlX3RhYmxlW3NhbXBsZV90YWJsZSRkaWZmX2dyb3VwcyA9PSAyICYgKCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIlc4XzEwIiB8IHNhbXBsZV90YWJsZSRwb29scyA9PSAiQk0iKSwgXQoKY291bnRzIDwtIGJpZ19jb3VudHNbLGNvbG5hbWVzKGJpZ19jb3VudHMpICVpbiUgcm93bmFtZXMoY29sZGF0YSldCmRkcyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50cywgY29sRGF0YSA9IGNvbGRhdGEsIGRlc2lnbiA9IH5iYXRjaCArIHBvb2xzKQoKZGVzZXEgPC0gREVTZXEoZGRzKQoKcmVzIDwtIHJlc3VsdHMoZGVzZXEsIGNvbnRyYXN0ID0gYygicG9vbHMiLCAiVzhfMTAiLCAiQk0iKSkKcmVzT3JkZXJlZCA8LSByZXNbb3JkZXIocmVzJHBhZGopLF0KcmVzT3JkZXJlZCA8LSBkYXRhLmZyYW1lKHJlc09yZGVyZWQpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFshaXMubmEocmVzT3JkZXJlZCRwYWRqKSxdCnJlc09yZGVyZWQgPC0gbGVmdF9qb2luKHJvd25hbWVzX3RvX2NvbHVtbihyZXNPcmRlcmVkLCB2YXIgPSAiZW5zZ2VuZSIpLCBncmNoMzgsIGJ5ID0gImVuc2dlbmUiKSAlPiUgCiAgZHBseXI6OnNlbGVjdChzeW1ib2wsbG9nMkZvbGRDaGFuZ2UscGFkaixiaW90eXBlKQpyZXNPcmRlcmVkIDwtIHJlc09yZGVyZWRbMTo1MDAsXQpkYXRhdGFibGUocmVzT3JkZXJlZCkKYGBgCgojI0NEMzQrQ0QzOC1DRDQ1UkEtIENTMTlfMjMgdiBCTQoKYGBge3J9CmNvbGRhdGEgPC0gc2FtcGxlX3RhYmxlW3NhbXBsZV90YWJsZSRkaWZmX2dyb3VwcyA9PSAyICYgKCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIkNTMTlfMjMiIHwgc2FtcGxlX3RhYmxlJHBvb2xzID09ICJCTSIpLCBdCgpjb3VudHMgPC0gYmlnX2NvdW50c1ssY29sbmFtZXMoYmlnX2NvdW50cykgJWluJSByb3duYW1lcyhjb2xkYXRhKV0KZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnRzLCBjb2xEYXRhID0gY29sZGF0YSwgZGVzaWduID0gfmJhdGNoICsgcG9vbHMpCgpkZXNlcSA8LSBERVNlcShkZHMpCgpyZXMgPC0gcmVzdWx0cyhkZXNlcSwgY29udHJhc3QgPSBjKCJwb29scyIsICJDUzE5XzIzIiwgIkJNIikpCnJlc09yZGVyZWQgPC0gcmVzW29yZGVyKHJlcyRwYWRqKSxdCnJlc09yZGVyZWQgPC0gZGF0YS5mcmFtZShyZXNPcmRlcmVkKQpyZXNPcmRlcmVkIDwtIHJlc09yZGVyZWRbIWlzLm5hKHJlc09yZGVyZWQkcGFkaiksXQpyZXNPcmRlcmVkIDwtIGxlZnRfam9pbihyb3duYW1lc190b19jb2x1bW4ocmVzT3JkZXJlZCwgdmFyID0gImVuc2dlbmUiKSwgZ3JjaDM4LCBieSA9ICJlbnNnZW5lIikgJT4lIAogIGRwbHlyOjpzZWxlY3Qoc3ltYm9sLGxvZzJGb2xkQ2hhbmdlLHBhZGosYmlvdHlwZSkKcmVzT3JkZXJlZCA8LSByZXNPcmRlcmVkWzE6NTAwLF0KZGF0YXRhYmxlKHJlc09yZGVyZWQpCmBgYAoKIyNDRDM0K0NEMzgtQ0Q0NVJBLSBDQiB2IEJNCgpgYGB7cn0KY29sZGF0YSA8LSBzYW1wbGVfdGFibGVbc2FtcGxlX3RhYmxlJGRpZmZfZ3JvdXBzID09IDIgJiAoIHNhbXBsZV90YWJsZSRwb29scyA9PSAiQ0IiIHwgc2FtcGxlX3RhYmxlJHBvb2xzID09ICJCTSIpLCBdCgpjb3VudHMgPC0gYmlnX2NvdW50c1ssY29sbmFtZXMoYmlnX2NvdW50cykgJWluJSByb3duYW1lcyhjb2xkYXRhKV0KZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnRzLCBjb2xEYXRhID0gY29sZGF0YSwgZGVzaWduID0gfmJhdGNoICsgcG9vbHMpCgpkZXNlcSA8LSBERVNlcShkZHMpCgpyZXMgPC0gcmVzdWx0cyhkZXNlcSwgY29udHJhc3QgPSBjKCJwb29scyIsICJDQiIsICJCTSIpKQpyZXNPcmRlcmVkIDwtIHJlc1tvcmRlcihyZXMkcGFkaiksXQpyZXNPcmRlcmVkIDwtIGRhdGEuZnJhbWUocmVzT3JkZXJlZCkKcmVzT3JkZXJlZCA8LSByZXNPcmRlcmVkWyFpcy5uYShyZXNPcmRlcmVkJHBhZGopLF0KcmVzT3JkZXJlZCA8LSBsZWZ0X2pvaW4ocm93bmFtZXNfdG9fY29sdW1uKHJlc09yZGVyZWQsIHZhciA9ICJlbnNnZW5lIiksIGdyY2gzOCwgYnkgPSAiZW5zZ2VuZSIpICU+JSAKICBkcGx5cjo6c2VsZWN0KHN5bWJvbCxsb2cyRm9sZENoYW5nZSxwYWRqLGJpb3R5cGUpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFsxOjUwMCxdCmRhdGF0YWJsZShyZXNPcmRlcmVkKQpgYGAKCiMjQ0QzNCtDRDE5KyB3MTJfMTMgdiBCTQoKYGBge3J9CmNvbGRhdGEgPC0gc2FtcGxlX3RhYmxlW3NhbXBsZV90YWJsZSRkaWZmX2dyb3VwcyA9PSAzICYgKCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIlcxMl8xMyIgfCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIkJNIiksIF0KCmNvdW50cyA8LSBiaWdfY291bnRzWyxjb2xuYW1lcyhiaWdfY291bnRzKSAlaW4lIHJvd25hbWVzKGNvbGRhdGEpXQpkZHMgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudHMsIGNvbERhdGEgPSBjb2xkYXRhLCBkZXNpZ24gPSB+YmF0Y2ggKyBwb29scykKCmRlc2VxIDwtIERFU2VxKGRkcykKCnJlcyA8LSByZXN1bHRzKGRlc2VxLCBjb250cmFzdCA9IGMoInBvb2xzIiwgIlcxMl8xMyIsICJCTSIpKQpyZXNPcmRlcmVkIDwtIHJlc1tvcmRlcihyZXMkcGFkaiksXQpyZXNPcmRlcmVkIDwtIGRhdGEuZnJhbWUocmVzT3JkZXJlZCkKcmVzT3JkZXJlZCA8LSBsZWZ0X2pvaW4ocm93bmFtZXNfdG9fY29sdW1uKHJlc09yZGVyZWQsIHZhciA9ICJlbnNnZW5lIiksIGdyY2gzOCwgYnkgPSAiZW5zZ2VuZSIpICU+JSAKICBkcGx5cjo6c2VsZWN0KHN5bWJvbCxsb2cyRm9sZENoYW5nZSxwYWRqLGJpb3R5cGUpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFsxOjUwMCxdCmRhdGF0YWJsZShyZXNPcmRlcmVkKQpgYGAKCiMjQ0QzNCtDRDE5KyB3OF8xMCB2IEJNCgoKYGBge3J9CmNvbGRhdGEgPC0gc2FtcGxlX3RhYmxlW3NhbXBsZV90YWJsZSRkaWZmX2dyb3VwcyA9PSAzICYgKCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIlc4XzEwIiB8IHNhbXBsZV90YWJsZSRwb29scyA9PSAiQk0iKSwgXQoKY291bnRzIDwtIGJpZ19jb3VudHNbLGNvbG5hbWVzKGJpZ19jb3VudHMpICVpbiUgcm93bmFtZXMoY29sZGF0YSldCmRkcyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50cywgY29sRGF0YSA9IGNvbGRhdGEsIGRlc2lnbiA9IH5iYXRjaCArIHBvb2xzKQoKZGVzZXEgPC0gREVTZXEoZGRzKQoKcmVzIDwtIHJlc3VsdHMoZGVzZXEsIGNvbnRyYXN0ID0gYygicG9vbHMiLCAiVzhfMTAiLCAiQk0iKSkKcmVzT3JkZXJlZCA8LSByZXNbb3JkZXIocmVzJHBhZGopLF0KcmVzT3JkZXJlZCA8LSBkYXRhLmZyYW1lKHJlc09yZGVyZWQpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFshaXMubmEocmVzT3JkZXJlZCRwYWRqKSxdCnJlc09yZGVyZWQgPC0gbGVmdF9qb2luKHJvd25hbWVzX3RvX2NvbHVtbihyZXNPcmRlcmVkLCB2YXIgPSAiZW5zZ2VuZSIpLCBncmNoMzgsIGJ5ID0gImVuc2dlbmUiKSAlPiUgCiAgZHBseXI6OnNlbGVjdChzeW1ib2wsbG9nMkZvbGRDaGFuZ2UscGFkaixiaW90eXBlKQpyZXNPcmRlcmVkIDwtIHJlc09yZGVyZWRbMTo1MDAsXQpkYXRhdGFibGUocmVzT3JkZXJlZCkKYGBgCgojI0NEMzQrQ0QxOSsgQ1MxOV8yMyB2IEJNCgpgYGB7cn0KY29sZGF0YSA8LSBzYW1wbGVfdGFibGVbc2FtcGxlX3RhYmxlJGRpZmZfZ3JvdXBzID09IDMgJiAoIHNhbXBsZV90YWJsZSRwb29scyA9PSAiQ1MxOV8yMyIgfCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIkJNIiksIF0KCmNvdW50cyA8LSBiaWdfY291bnRzWyxjb2xuYW1lcyhiaWdfY291bnRzKSAlaW4lIHJvd25hbWVzKGNvbGRhdGEpXQpkZHMgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudHMsIGNvbERhdGEgPSBjb2xkYXRhLCBkZXNpZ24gPSB+YmF0Y2ggKyBwb29scykKCmRlc2VxIDwtIERFU2VxKGRkcykKCnJlcyA8LSByZXN1bHRzKGRlc2VxLCBjb250cmFzdCA9IGMoInBvb2xzIiwgIkNTMTlfMjMiLCAiQk0iKSkKcmVzT3JkZXJlZCA8LSByZXNbb3JkZXIocmVzJHBhZGopLF0KcmVzT3JkZXJlZCA8LSBkYXRhLmZyYW1lKHJlc09yZGVyZWQpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFshaXMubmEocmVzT3JkZXJlZCRwYWRqKSxdCnJlc09yZGVyZWQgPC0gbGVmdF9qb2luKHJvd25hbWVzX3RvX2NvbHVtbihyZXNPcmRlcmVkLCB2YXIgPSAiZW5zZ2VuZSIpLCBncmNoMzgsIGJ5ID0gImVuc2dlbmUiKSAlPiUgCiAgZHBseXI6OnNlbGVjdChzeW1ib2wsbG9nMkZvbGRDaGFuZ2UscGFkaixiaW90eXBlKQpyZXNPcmRlcmVkIDwtIHJlc09yZGVyZWRbMTo1MDAsXQpkYXRhdGFibGUocmVzT3JkZXJlZCkKYGBgCgojI0NEMzQrQ0QxOSsgQ0IgdiBCTQoKYGBge3J9CmNvbGRhdGEgPC0gc2FtcGxlX3RhYmxlW3NhbXBsZV90YWJsZSRkaWZmX2dyb3VwcyA9PSAzICYgKCBzYW1wbGVfdGFibGUkcG9vbHMgPT0gIkNCIiB8IHNhbXBsZV90YWJsZSRwb29scyA9PSAiQk0iKSwgXQoKY291bnRzIDwtIGJpZ19jb3VudHNbLGNvbG5hbWVzKGJpZ19jb3VudHMpICVpbiUgcm93bmFtZXMoY29sZGF0YSldCmRkcyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50cywgY29sRGF0YSA9IGNvbGRhdGEsIGRlc2lnbiA9IH5iYXRjaCArIHBvb2xzKQoKZGVzZXEgPC0gREVTZXEoZGRzKQoKcmVzIDwtIHJlc3VsdHMoZGVzZXEsIGNvbnRyYXN0ID0gYygicG9vbHMiLCAiQ0IiLCAiQk0iKSkKcmVzT3JkZXJlZCA8LSByZXNbb3JkZXIocmVzJHBhZGopLF0KcmVzT3JkZXJlZCA8LSBkYXRhLmZyYW1lKHJlc09yZGVyZWQpCnJlc09yZGVyZWQgPC0gcmVzT3JkZXJlZFshaXMubmEocmVzT3JkZXJlZCRwYWRqKSxdCnJlc09yZGVyZWQgPC0gbGVmdF9qb2luKHJvd25hbWVzX3RvX2NvbHVtbihyZXNPcmRlcmVkLCB2YXIgPSAiZW5zZ2VuZSIpLCBncmNoMzgsIGJ5ID0gImVuc2dlbmUiKSAlPiUgCiAgZHBseXI6OnNlbGVjdChzeW1ib2wsbG9nMkZvbGRDaGFuZ2UscGFkaixiaW90eXBlKQpyZXNPcmRlcmVkIDwtIHJlc09yZGVyZWRbMTo1MDAsXQpkYXRhdGFibGUocmVzT3JkZXJlZCkKYGBg